home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Sherlock 2.0 / DevLibSrc / Main_DevLib / LIBos.c < prev    next >
Text File  |  1996-03-12  |  7KB  |  426 lines

  1. /*
  2.     devlib: application text and binary output routines.
  3.     
  4.     source:  LIBos.c.
  5.     started: December 13, 1993.
  6.     version:
  7.         September 26, 1995.
  8.             Changed loop in os from: while (c = *s++) { to: while (*s) { c = *s++.
  9.             This eliminates a Code Warrior warning.
  10.         July 17, 1994.
  11.             Added ocblanks.
  12.         June 2, 1994.
  13.             Added olong.
  14.         May 24, 1994.
  15.             Added ocnl and ocnls.
  16.             Added opads.
  17.         May 4, 1994.
  18.             Made out_bytes_offset a global variable.
  19.         April 21, 1994.
  20.             Added ofloat routine.
  21.         March 31, 1994.
  22.             Bug fix: do ecnls(2) in out_bytes only when tracing!
  23.         March 24, 1994.
  24.             Improved tracing in out_bytes.
  25.         February 13, 1994.
  26.             Added ochar.
  27.             Added opadhex.
  28.         January 27, 1994.
  29.             Bug fix: os() writes *only* to the os_text_file!
  30.             Revised os() to handle tabs correctly.
  31.         January 7, 1994.
  32. */
  33.  
  34. #include <LIBlib.h>
  35.  
  36. #include <LIBio.h>
  37. #include <LIBos.h>
  38.  
  39. #include <ctype.h>
  40. #include <string.h>
  41.  
  42. /*
  43.     Define the size of the conversion buffers.
  44. */
  45. #define OS_BUF_SIZE 200
  46.  
  47. /*
  48.     Prototypes of internal routines.
  49. */
  50. static void    ojustify(char * buffer, int length, int field_length);
  51.  
  52. /*
  53.     Globals owned by this module.
  54. */
  55. io_file * os_bytes_file = NULL;    /* The file used by the os routines. */
  56. io_file * os_text_file = NULL;    /* The map output file. */
  57.  
  58. void
  59. onl(void)
  60. {
  61.     os("\n");
  62. }
  63.  
  64. /*
  65.     All text file output eventually comes here.
  66. */
  67. void
  68. os(register char * s)
  69. {
  70.     FTAG("os");
  71.     TICK(ftag);    
  72.             
  73.     // STATB(ftag);    // Getting timing measurements is too costly here
  74.  
  75.     if (s && os_text_file) {
  76.     
  77.         /* Load registers from the file struct. */
  78.         register char * ptr        = os_text_file -> io_file_pointer;
  79.         register long count        = os_text_file -> io_file_count;
  80.         register long bufsize    = os_text_file -> io_file_bufsize;
  81.         register char c;
  82.         
  83.         while(*s) {
  84.         
  85.             c = *s++;
  86.         
  87.             /* Keep track of consecutive newlines. */
  88.             if (c == '\n') {
  89.                 ++io_nl_count;
  90.                 io_line_count = 0;
  91.                 
  92.                 /* This step is needed now that we are using ANSI_IO.c */
  93.                 #ifdef applec
  94.                     c = '\r';
  95.                 #endif
  96.             }
  97.             else if (c == '\t') {
  98.  
  99.                 /* 4-space tabs. */
  100.                 int width = (4 - (io_line_count % 4));
  101.                 int i;
  102.                 for (i = 0; i < width; i++) {
  103.                 
  104.                     if (count == bufsize) {
  105.             
  106.                         os_text_file -> io_file_count = count;
  107.                         io_write(os_text_file);
  108.                         ptr = os_text_file -> io_file_buffer;
  109.                         count = 0;
  110.                     }
  111.                     
  112.                     *ptr++ = ' ';
  113.                     ++count;
  114.                 }
  115.                 io_nl_count = 0;
  116.                 io_line_count += width;
  117.                 continue;
  118.             }
  119.             else {
  120.                 io_nl_count = 0;
  121.                 io_line_count++;
  122.             }
  123.             
  124.             if (count == bufsize) {
  125.             
  126.                 os_text_file -> io_file_count = count;
  127.                 io_write(os_text_file);
  128.                 ptr = os_text_file -> io_file_buffer;
  129.                 count = 0;
  130.             }
  131.             
  132.             *ptr++ = c;
  133.             ++count;
  134.         }
  135.         
  136.         /* Update the file struct from the registers. */
  137.         os_text_file -> io_file_pointer = ptr;
  138.         os_text_file -> io_file_count = count;
  139.     }
  140.     
  141.     // STATX(ftag); // Getting timing measurements is too costly here
  142. }
  143.  
  144. void
  145. oblank(void)
  146. {
  147.     os(" ");
  148. }
  149.  
  150. void
  151. oblanks(register int n)
  152. {
  153.     register int i;
  154.     
  155.     for(i = 0; i < n; i++) {
  156.         oblank();
  157.     }
  158. }
  159.  
  160. void
  161. ocblanks(short n)
  162. {
  163.     if (os_text_file) {
  164.         n = - os_text_file -> io_file_count;
  165.         n = min(n, os_text_file -> io_file_bufsize);
  166.         oblanks(n);
  167.     }
  168. }
  169.  
  170. void
  171. ochar(int c)
  172. {
  173.     char buffer[2];
  174.  
  175.     buffer [0] = c;
  176.     buffer [1] = '\0';
  177.     os(buffer);
  178. }
  179.  
  180. /*
  181.     Output condictional newlines.
  182. */
  183. void
  184. ocnl(void)
  185. {
  186.     if (io_nl_count == 0) {
  187.         onl();
  188.     }
  189. }
  190.  
  191. void
  192. ocnls(int n)
  193. {
  194.     register int i;
  195.     for (i = n - io_nl_count; i > 0; i--) {
  196.         onl();
  197.     }
  198. }
  199.  
  200. void
  201. ocs(void)
  202. {
  203.     os(", ");
  204. }
  205.  
  206. /*
  207.     This routine must make no assumptions about size of floats.
  208. */
  209. void
  210. ofloat (register char * p, int size)
  211. {
  212.     register long val = 0;
  213.     if (p == NULL) {
  214.         fatal(es("ofloat: NULL pointer"));
  215.     }
  216.     
  217.     while(size-- > 0) {
  218.         val = *p++;
  219.         val &= 0xff;
  220.         opadhex(val, 2);
  221.     }
  222. }
  223.  
  224. void
  225. ohex(long hex)
  226. {
  227.     opadhex(hex, 0);
  228. }
  229.  
  230. void
  231. oint(int i)
  232. {
  233.     char buf [OS_BUF_SIZE];
  234.     sprintf(buf, "%d", i);
  235.     os(buf);
  236. }
  237.  
  238. static void
  239. ojustify(char * buffer, int length, int field_length)
  240. {
  241.     if (field_length < 0) {
  242.  
  243.         /* Left justify */
  244.         os(buffer);
  245.         oblanks(-field_length - length);
  246.     }
  247.     else {
  248.         
  249.         /* Right justify */
  250.         oblanks(field_length - length);
  251.         os(buffer);
  252.     }
  253. }
  254.  
  255. /*
  256.     Output a long.
  257. */
  258. void
  259. olong(long l)
  260. {
  261.     char buf [OS_BUF_SIZE];
  262.     sprintf(buf, "%ld", l);
  263.     os(buf);
  264. }
  265.  
  266. /*
  267.     Output a long in hex format, justified in a field of the given length.
  268. */
  269. void
  270. opadhex(long hex, int field)
  271. {
  272.     char buf [OS_BUF_SIZE];
  273.     int n;
  274.  
  275.     sprintf(buf, "%lx", hex);
  276.     n = field - strlen(buf);
  277.     while (n-- > 0) {
  278.         ochar('0');
  279.     }
  280.     os(buf);
  281. }
  282.  
  283. void
  284. opadlong(long l, int field)
  285. {
  286.     char buf [OS_BUF_SIZE];
  287.  
  288.     ojustify(buf, sprintf(buf, "%ld", l), field);
  289. }
  290.  
  291. void
  292. opadptr(void * p, int field)
  293. {
  294.     char buf [OS_BUF_SIZE];
  295.  
  296.     ojustify(buf, sprintf(buf, "%p", p), field);
  297. }
  298.  
  299. void
  300. opads(char * s, int field)
  301. {
  302.     ojustify(s, strlen(s), field);
  303. }
  304.  
  305. void
  306. opaduint(uint ui, int field)
  307. {
  308.     char buf [OS_BUF_SIZE];
  309.  
  310.     ojustify(buf, sprintf(buf, "%u", ui), field);
  311. }
  312.  
  313. void
  314. opadulong(ulong ul, int field)
  315. {
  316.     char buf [OS_BUF_SIZE];
  317.  
  318.     ojustify(buf, sprintf(buf, "%lu", ul), field);
  319. }
  320.  
  321. void
  322. optr(void * p)
  323. {
  324.     opadptr(p, 0);
  325. }
  326.  
  327. void
  328. otab(void)
  329. {
  330.     os("\t");
  331. }
  332.  
  333. void
  334. otabs(register int tab_count)
  335. {
  336.     while (tab_count-- > 0) {
  337.         os("\t");
  338.     }
  339. }
  340.  
  341. void
  342. ouint(uint ui)
  343. {
  344.     opaduint(ui, 0);
  345. }
  346.  
  347. void
  348. oulong(ulong ul)
  349. {
  350.     char buf [OS_BUF_SIZE];
  351.     sprintf(buf, "%lu", ul);
  352.     os(buf);
  353. }
  354.  
  355. /*
  356.     All binary output is created using the out_bytes routine.
  357.     This routine is called very often; it should be as fast as possible.
  358. */
  359. #define CHARS_PER_LINE 8
  360. #define TAG_SIZE 26            /* 26 makes the traces look best. */
  361.  
  362. ulong out_bytes_offset = 0;
  363.  
  364. void
  365. out_bytes(register char * byte_ptr, register ulong byte_count, char * dtag)
  366. {
  367.     FTAG("out_bytes");
  368.     
  369.     /* Load registers from the file struct. */
  370.     register char * ptr        = os_bytes_file -> io_file_pointer;
  371.     register long count        = os_bytes_file -> io_file_count;
  372.     register long bufsize    = os_bytes_file -> io_file_bufsize;
  373. #ifdef SHERLOCK
  374.     ulong local_offset = 0;
  375.     bool line_one_flag = TRUE;
  376. #endif
  377.  
  378.     TRACEPB(ftag, epads(dtag, TAG_SIZE); eblank());
  379.         
  380.     ASSERT(os_bytes_file);
  381.  
  382.     while(byte_count--) {
  383.  
  384.         /* Write the file buffer if it is full. */
  385.         if (count == bufsize) {
  386.  
  387.             os_bytes_file -> io_file_count = count;
  388.             io_write(os_bytes_file);
  389.             ptr = os_bytes_file -> io_file_buffer;
  390.             count = 0;
  391.         }
  392.  
  393.         /* Trace the next character. */
  394.         TRACEN(ftag,
  395.             char c = *byte_ptr;
  396.             if ((local_offset % CHARS_PER_LINE) == 0) {
  397.                 if (!line_one_flag) {
  398.                     es(ftag); es(": "); eblanks(TAG_SIZE); eblank();
  399.                 }
  400.                 line_one_flag = FALSE;
  401.                 epadhex(out_bytes_offset,4); es(": ");
  402.             }
  403.             epadhex(c & 0xff,2);
  404.             eblank();
  405.             if ((local_offset % CHARS_PER_LINE) == CHARS_PER_LINE-1) {
  406.                 ecnl();
  407.             }
  408.             out_bytes_offset++;
  409.             local_offset++;
  410.         );
  411.         
  412.         /* Put the next character into the buffer. */
  413.         *ptr++ = *byte_ptr++;
  414.         ++count;
  415.     }
  416.     
  417.     TRACEN(ftag, ecnl());
  418.  
  419.     /* Update the file struct from the registers. */
  420.     os_bytes_file -> io_file_pointer = ptr;
  421.     os_bytes_file -> io_file_count = count;
  422.  
  423.     STATX(ftag);
  424. }
  425.  
  426.